import { useObservable } from '@gnlab/utils/env-react/rx'
import { Button } from 'antd'
import { OrderedMap } from 'immutable'
import { BehaviorSubject } from 'rxjs'
import { getSender, type ChatOwner } from '@/desktop/logics/chat/info'
import { useRecordsScrolling, makeElementId } from '@/desktop/logics/chat/records'
import { useStreams } from '@/lib/utils'
import services from '@/services'
import type { ChatRecord } from '@/services/contact-chat'
import { type ContactWithTransfer } from '@/services/contacts'
import { Record, RecordModals } from '../record'
import { modals } from '../record/modals'
import { AccessUnread } from './AccessUnread'
import { LoadingMore } from './LoadingMore'
import './index.module.less'

// “聊天记录多选”开关
// 开启时可传入 true 或一条聊天记录（会被默认选中）
export const chatRecordsChoosingSubject = new BehaviorSubject<boolean | ChatRecord>(false)

export function ChatRecords(props: { contact: ContactWithTransfer; owner: ChatOwner }) {
  const { contact, owner } = props

  const [account, groupMembers, observingReadonly] = useStreams(
    services.auth.account$,
    services.groups.members,
    services.auth.observing.readonly$,
  )

  const groupMemberMap = useMemo(
    () => new Map(groupMembers.map(m => [m.userId, m])),
    [groupMembers],
  )
  const customGetSender = (record: ChatRecord) =>
    getSender({ record, contact, owner, groupMembers: groupMemberMap })

  const recordsElementRef = useRef<HTMLDivElement>(null)
  const { records, isLoading, atBottom, scrollToFirstUnread } = useRecordsScrolling({
    contact,
    container: recordsElementRef.current,
  })

  const [choosing, setChoosing] = useState<OrderedMap<string, ChatRecord> | null>(null)
  const switchChoose = useCallback((record: ChatRecord) => {
    setChoosing(choosing => {
      if (!choosing) return null
      return choosing.has(record.id) ? choosing.delete(record.id) : choosing.set(record.id, record)
    })
  }, [])
  useObservable(chatRecordsChoosingSubject, flag => {
    setChoosing(choosing => {
      if (flag === false) return null
      if (flag === true) return choosing ?? OrderedMap() // 已经处于多选状态下，再次开启，保留原选中的记录
      return (choosing ?? OrderedMap()).set(flag.id, flag)
    })
  })
  useEffect(() => {
    return () => chatRecordsChoosingSubject.next(false)
  }, [])
  function executeForward() {
    if (!choosing) return
    void modals.forward.next([...choosing.values()])
    chatRecordsChoosingSubject.next(false)
  }

  return <>
    {choosing ? (
      <div styleName="choosing">
        <span styleName="count">已选中:{choosing.size}条</span>
        <Button type="link" disabled={!choosing.size} onClick={executeForward}>
          转发
        </Button>
        <a onClick={() => chatRecordsChoosingSubject.next(false)}>取消多选</a>
      </div>
    ) : null}

    <div styleName="records-container">
      <LoadingMore isLoading={isLoading} />

      <div styleName="records" ref={recordsElementRef}>
        {account
          ? records.map(record => <Record
              key={record.id}
              id={makeElementId(record.id)}
              record={record}
              sender={customGetSender(record)}
              contact={contact}
              account={account}
              readonly={!!observingReadonly}
              choosed={choosing === null ? undefined : choosing.has(record.id)}
              switchChoose={switchChoose}
            />)
          : null}
      </div>

      <RecordModals />

      <AccessUnread contact={contact} visible={!atBottom} onClick={scrollToFirstUnread} />
    </div>
  </>
}
